#include"ProcessServer.h"
MusicServer::MusicServer(int port, int ThreadNum)
{
     pool=new ThreadPool(ThreadNum);
     mainreactor=new EpollReactor;   
     m_port=port;
     listenfd=initsocket();  //初始化套接字
     if(listenfd<0){
        cout<<"Error initsocket fail"<<endl;
        return ;
     }
}

MusicServer::~MusicServer()
{
    delete pool;
    delete mainreactor;
}

void MusicServer::Run()
{   
    if(prepare()<0){  //将监听的文件描述符挂在主反应堆上
       cout<<"Error prepare fail"<<endl;
       return ;
    }  
    this->pool->Run();
    this->mainreactor->run();
}

int MusicServer::initsocket()
{
   int listenfd=socket(AF_INET,SOCK_STREAM,0);//创建套接字
   if(listenfd==-1){
      //sys_error("socket is error");
   }
   //设置端口复用
   int opt=1;
   setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));

   //绑定地址结构
   struct sockaddr_in saddr,caddr;
   saddr.sin_port=htons(m_port);
   saddr.sin_addr.s_addr=htonl(INADDR_ANY);
   saddr.sin_family=AF_INET;
   bind(listenfd,(struct sockaddr*)&saddr,sizeof(saddr));
   //监听
   listen(listenfd,128);
   return listenfd;
}

int MusicServer::prepare()
{
   FdInfo info(listenfd,1,AcceptConnect,nullptr,nullptr,this);
   mainreactor->setfdinfo(info);
   int ret=mainreactor->add();
   return ret;
}
// 打印客户端地址
void printClientAddress(const struct sockaddr_in* clientAddr) {
    char ip[INET_ADDRSTRLEN];
    inet_ntop(AF_INET, &(clientAddr->sin_addr), ip, INET_ADDRSTRLEN);
    unsigned short port = ntohs(clientAddr->sin_port);
    printf("Client Address: %s:%u\n", ip, port);
}
int MusicServer::AcceptConnect(void *tcp)
{
   MusicServer*server=static_cast<MusicServer*>(tcp);
   struct sockaddr_in client_addr;
   socklen_t addr_len = sizeof(client_addr);
   int cfd=accept(server->listenfd,(struct sockaddr*)&client_addr, &addr_len);  //接受客户端连接请求
   printClientAddress(&client_addr);
   ProcessServer*Process=new ProcessServer(cfd,server->pool->TakeReactor());
   return 1;
}
